import axios, { InternalAxiosRequestConfig, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
import { useUserStore } from '@/store/modules/user'
import { ApiStatus } from './status'
import { HttpError, handleError, showError } from './error'
import { $t } from '@/locales'

// 常量定义
const REQUEST_TIMEOUT = 15000 // 请求超时时间(毫秒)
const LOGOUT_DELAY = 1000 // 退出登录延迟时间(毫秒)
const MAX_RETRIES = 0 // 最大重试次数
const RETRY_DELAY = 1000 // 重试延迟时间(毫秒)
const TOKEN_EXPIRED_CODE = ApiStatus.unauthorized // Token 过期状态码
const TOKEN_REFRESH_ENDPOINT = '/auth/refresh' // Token 刷新接口

// 扩展 AxiosRequestConfig 类型
interface ExtendedAxiosRequestConfig extends AxiosRequestConfig {
  showErrorMessage?: boolean
  headers?: Record<string, any>
  _retry?: boolean // 用于标记是否正在重试
}

// 刷新 token 相关状态
let isRefreshing = false
let refreshSubscribers: ((token: string) => void)[] = []

// 处理等待中的请求
const onRefreshed = (token: string) => {
  refreshSubscribers.forEach(callback => callback(token))
  refreshSubscribers = []
}

// 添加等待中的请求
const addRefreshSubscriber = (callback: (token: string) => void) => {
  refreshSubscribers.push(callback)
}

const axiosInstance = axios.create({
  timeout: REQUEST_TIMEOUT,
  baseURL: import.meta.env.VITE_API_URL,
  withCredentials: true,
  transformRequest: [
    (data) => {
      if (data instanceof FormData) {
        return data
      }
      return JSON.stringify(data)
    }
  ],
  validateStatus: (status) => status >= 200 && status < 300,
  headers: {
    get: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' },
    post: { 'Content-Type': 'application/json;charset=utf-8' }
  },
  transformResponse: [
    (data, headers) => {
      const contentType = headers?.['content-type']
      if (contentType && contentType.includes('application/json')) {
        try {
          return JSON.parse(data)
        } catch {
          return data
        }
      }
      return data
    }
  ]
})

// 请求拦截器
axiosInstance.interceptors.request.use(
  (request: InternalAxiosRequestConfig) => {
    const { accessToken } = useUserStore()
    if (accessToken) {
      request.headers = request.headers || {}
      request.headers.Authorization = `Bearer ${accessToken}`
    }
    
    if (request.data instanceof FormData) {
      delete request.headers?.['Content-Type']
    } else if (request.headers) {
      request.headers['Content-Type'] = 'application/json'
    }
    
    return request
  },
  (error) => {
    showError(new HttpError($t('httpMsg.requestConfigError'), ApiStatus.error))
    return Promise.reject(error)
  }
)

// 响应拦截器
axiosInstance.interceptors.response.use(
  (response: AxiosResponse<Api.Http.BaseResponse>) => {
    const { code, msg } = response.data
    switch (code) {
      case ApiStatus.success:
        return response
      case ApiStatus.unauthorized:
        logOut()
        throw new HttpError(msg || $t('httpMsg.unauthorized'), ApiStatus.unauthorized)
      default:
        throw new HttpError(msg || $t('httpMsg.requestFailed'), code)
    }
  },
  async (error) => {
    const originalRequest = error.config
    const userStore = useUserStore()
    
    // 处理 token 过期情况
    if (error.response?.status === TOKEN_EXPIRED_CODE && 
        !originalRequest._retry && 
        userStore.refreshToken) {
			
		console.log('userStore.refreshToken=',userStore.refreshToken);
			
      
      if (isRefreshing) {
        // 如果正在刷新 token，将请求加入队列
        return new Promise((resolve) => {
          addRefreshSubscriber((newToken: string) => {
            originalRequest.headers.Authorization = `Bearer ${newToken}`
            resolve(axiosInstance(originalRequest))
          })
        })
      }
      
      originalRequest._retry = true
      isRefreshing = true
      
      try {
        // 尝试刷新 token
        const { data } = await axios.post(TOKEN_REFRESH_ENDPOINT, {
          refreshToken: userStore.refreshToken
        }, {
          baseURL: import.meta.env.VITE_API_URL,
          withCredentials: true
        })
		
		console.log("data.accessToke=",data?.data.accessToke);
		console.log("data.refreshToken=",data?.data.refreshToken);
		
        // 保存新 token
        userStore.setToken(data?.data.accessToken, data?.data.refreshToken)
        // 处理等待中的请求
        onRefreshed(data?.data.accessToken)
        // 重试原始请求
        originalRequest.headers.Authorization = `Bearer ${data?.data.accessToken}`
        return axiosInstance(originalRequest)
      } catch (refreshError) {
        // 刷新 token 失败，执行登出
        userStore.logOut()
		// 处理类型问题
		if (refreshError instanceof Error) {
		  const axiosError = refreshError as AxiosError<Api.Http.BaseResponse>
		  return Promise.reject(handleError(axiosError))
		} else {
		  // 如果不是 Error 类型，创建一个通用的 AxiosError
		  const genericError = new Error('Unknown refresh token error') as AxiosError<Api.Http.BaseResponse>
		  return Promise.reject(handleError(genericError))
		}
      } finally {
        isRefreshing = false
      }
    }
    
    return Promise.reject(handleError(error))
  }
)

// 请求重试函数
async function retryRequest<T>(
  config: ExtendedAxiosRequestConfig,
  retries: number = MAX_RETRIES
): Promise<T> {
  try {
    return await request<T>(config)
  } catch (error) {
    if (retries > 0 && error instanceof HttpError && shouldRetry(error.code)) {
      await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY))
      return retryRequest<T>(config, retries - 1)
    }
    throw error
  }
}

// 判断是否需要重试
function shouldRetry(statusCode: number): boolean {
  return [
    ApiStatus.requestTimeout,
    ApiStatus.internalServerError,
    ApiStatus.badGateway,
    ApiStatus.serviceUnavailable,
    ApiStatus.gatewayTimeout
  ].includes(statusCode)
}

// 请求函数
async function request<T = any>(config: ExtendedAxiosRequestConfig): Promise<T> {
  // 对 POST | PUT 请求特殊处理
  if (['POST', 'PUT'].includes(config.method?.toUpperCase() || '')) {
    if (config.params && !config.data) {
      config.data = config.params
      config.params = undefined
    }
  }

  // 合并自定义 headers
  const axiosConfig = { ...config }
  if (config.headers) {
    const method = config.method?.toLowerCase() || 'post'
    const defaultHeaders = axiosInstance.defaults.headers[method]
    axiosConfig.headers = {
      ...(typeof defaultHeaders === 'object' && defaultHeaders !== null ? defaultHeaders : {}),
      ...config.headers
    }
  }

  try {
    const res = await axiosInstance.request<Api.Http.BaseResponse<T>>(axiosConfig)
    return res.data.data as T
  } catch (error) {
    if (error instanceof HttpError) {
      const showErrorMessage = config.showErrorMessage !== false
      showError(error, showErrorMessage)
    }
    return Promise.reject(error)
  }
}

// API 方法集合
const api = {
  get<T>(config: ExtendedAxiosRequestConfig): Promise<T> {
    return retryRequest<T>({ ...config, method: 'GET' })
  },
  post<T>(config: ExtendedAxiosRequestConfig): Promise<T> {
    return retryRequest<T>({ ...config, method: 'POST' })
  },
  put<T>(config: ExtendedAxiosRequestConfig): Promise<T> {
    return retryRequest<T>({ ...config, method: 'PUT' })
  },
  del<T>(config: ExtendedAxiosRequestConfig): Promise<T> {
    return retryRequest<T>({ ...config, method: 'DELETE' })
  },
  request<T>(config: ExtendedAxiosRequestConfig): Promise<T> {
    return retryRequest<T>({ ...config })
  }
}

// 退出登录函数
const logOut = (): void => {
  setTimeout(() => {
    useUserStore().logOut()
  }, LOGOUT_DELAY)
}

export default api
export { axiosInstance }